home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / tde40.zip / window.c < prev    next >
C/C++ Source or Header  |  1994-06-05  |  42KB  |  1,326 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    dte - Doug's Text Editor program - window module
  10.  * Purpose: This file contains the code associated with opening and sizing
  11.  *           windows, and also displaying the help window.
  12.  * File:    window.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 12, 1989
  16.  */
  17. /*********************  end of original comments   ********************/
  18.  
  19.  
  20. /*
  21.  * The window routines have been EXTENSIVELY rewritten.  Some routines were
  22.  * changed so only one logical function is carried out, eg. 'initialize_window'.
  23.  * I like the Microsoft way of resizing windows - just press the up and down
  24.  * arrows to adjust the window to desired size.  I also like pressing one key
  25.  * to change windows.  All of which are implemented in TDE.
  26.  *
  27.  * In TDE, version 1.4, I added support for vertical windows.
  28.  *
  29.  * New editor name:  TDE, the Thomson-Davis Editor.
  30.  * Author:           Frank Davis
  31.  * Date:             June 5, 1991, version 1.0
  32.  * Date:             July 29, 1991, version 1.1
  33.  * Date:             October 5, 1991, version 1.2
  34.  * Date:             January 20, 1992, version 1.3
  35.  * Date:             February 17, 1992, version 1.4
  36.  * Date:             April 1, 1992, version 1.5
  37.  * Date:             June 5, 1992, version 2.0
  38.  * Date:             October 31, 1992, version 2.1
  39.  * Date:             April 1, 1993, version 2.2
  40.  * Date:             June 5, 1993, version 3.0
  41.  * Date:             August 29, 1993, version 3.1
  42.  * Date:             November 13, 1993, version 3.2
  43.  * Date:             June 5, 1994, version 4.0
  44.  *
  45.  * This modification of Douglas Thomson's code is released into the
  46.  * public domain, Frank Davis.  You may distribute it freely.
  47.  */
  48.  
  49. #include "tdestr.h"
  50. #include "common.h"
  51. #include "define.h"
  52. #include "tdefunc.h"
  53.  
  54.  
  55. /*
  56.  * Name:    initialize_window
  57.  * Purpose: To open a new window
  58.  * Date:    June 5, 1991
  59.  * Modified: November 13, 1993, Frank Davis per Byrial Jensen
  60.  * Returns: OK if window opened successfully
  61.  *          ERROR if anything went wrong
  62.  * Notes:   If this is first window, then set up as normal displayed window;
  63.  *          otherwise, make the present window invisible and open a new
  64.  *          window in the same screen location as the old one.
  65.  *
  66.  * Change:  Use of new function get_next_letter( )
  67.  */
  68. int  initialize_window( void )
  69. {
  70. int  top;
  71. int  bottom;
  72. int  start_col;
  73. int  end_col;
  74. TDE_WIN *wp;        /* used for scanning windows */
  75. TDE_WIN *window;
  76. register file_infos *fp;     /* used for scanning files */
  77. register int rc;
  78. line_list_ptr ll;
  79. line_list_ptr temp_ll;
  80. long n;
  81.  
  82.    rc = OK;
  83.    window = g_status.current_window;
  84.    fp = g_status.current_file;
  85.    if (window == NULL) {
  86.       /*
  87.        * special case if this is the first window on screen.
  88.        */
  89.       top = start_col = 0;
  90.       bottom  = g_display.nlines;
  91.       end_col = g_display.ncols - 1;
  92.    } else {
  93.       /*
  94.        * else put the new window in same place as current window.
  95.        *  make current window invisible.  new window becomes current window.
  96.        */
  97.       top       = window->top_line - 1;
  98.       bottom    = window->bottom_line;
  99.       start_col = window->start_col;
  100.       end_col   = window->end_col;
  101.    }
  102.  
  103.    assert( top < bottom );
  104.    assert( start_col < end_col );
  105.    assert( fp != NULL );
  106.  
  107.    if (create_window( &wp, top, bottom, start_col, end_col, fp ) == ERROR) {
  108.       /*
  109.        * out of memory
  110.        */
  111.       error( WARNING, bottom, main4 );
  112.  
  113.       /*
  114.        * This is a real nuisance. We had room for the file and the
  115.        *  file structure, but not enough for the window as well.
  116.        * Now we must free all the memory that has already been
  117.        *  allocated.
  118.        */
  119.       if (fp->ref_count == 0) {
  120.  
  121.          /*
  122.           * remove fp from file pointer list.
  123.           */
  124.          if (fp->prev != NULL)
  125.             fp->prev->next = fp->next;
  126.          else
  127.             g_status.file_list = fp->next;
  128.  
  129.          if (fp->next != NULL)
  130.             fp->next->prev = fp->prev;
  131.  
  132.          /*
  133.           * free the undo stack, line pointers, and linked list.
  134.           */
  135.  
  136.          ll = fp->undo_top;
  137.          while (ll != NULL) {
  138.             temp_ll = ll->next;
  139.             if (ll->line != NULL)
  140.                my_free( ll->line );
  141.             my_free( ll );
  142.             ll = temp_ll;
  143.          }
  144.  
  145.          ll = fp->line_list;
  146.          while (ll != NULL) {
  147.             temp_ll = ll->next;
  148.             if (ll->line != NULL)
  149.                my_free( ll->line );
  150.             my_free( ll );
  151.             ll = temp_ll;
  152.          }
  153.  
  154. #if defined( __MSC__ )
  155.          _fheapmin( );
  156. #endif
  157.  
  158.          free( fp );
  159.          wp = g_status.current_window;
  160.          if (wp != NULL && wp->visible)
  161.             g_status.current_file = wp->file_info;
  162.          else
  163.             g_status.stop = TRUE;
  164.       }
  165.       rc = ERROR;
  166.    }
  167.  
  168.    if (rc != ERROR) {
  169.       /*
  170.        * set up the new cursor position as appropriate
  171.        */
  172.       wp->ccol = wp->start_col;
  173.       wp->rcol = wp->bcol = 0;
  174.  
  175.       /*
  176.        * if user entered something like +10 file.doc, make line 10 the
  177.        *  current line.
  178.        */
  179.       wp->ll    = fp->line_list;
  180.       wp->rline = 1L;
  181.       if (g_status.jump_to > 0  &&  g_status.jump_to <= fp->length) {
  182.          ll = wp->ll;
  183.          n = 1;
  184.          for (; n < g_status.jump_to; n++) {
  185.             wp->bin_offset += ll->len;
  186.             ll = ll->next;
  187.          }
  188.          wp->rline = g_status.jump_to;
  189.          wp->ll    = ll;
  190.       }
  191.       wp->visible = TRUE;
  192.       wp->letter = get_next_letter( fp->next_letter++ );
  193.       if (window != NULL)
  194.          window->visible = FALSE;
  195.  
  196.       /*
  197.        * the new window becomes the current window.
  198.        */
  199.       g_status.current_window = wp;
  200.       g_status.jump_to = 0;
  201.    }
  202.    return( rc );
  203. }
  204.  
  205.  
  206. /*
  207.  * Name:    get_next_letter
  208.  * Purpose: To find next letter to use as a window name
  209.  * Date:    August 29, 1993
  210.  * Author:  Byrial Jensen
  211.  * Passed:  next_letter:  The number window to create starting from 0
  212.  *          (Yes, the name is not very good, but I want to keep the
  213.  *          changes as small as possible)
  214.  */
  215. int  get_next_letter( int next_letter )
  216. {
  217.    if (next_letter + 1 > (int)strlen( windowletters ) )
  218.       return( LAST_WINDOWLETTER );
  219.    else
  220.       return( (int) (windowletters[next_letter]) );
  221. }
  222.  
  223.  
  224. /*
  225.  * Name:    next_window
  226.  * Purpose: To move to the next visible window.
  227.  * Date:    June 5, 1991
  228.  * Passed:  window:  pointer to current window
  229.  * Notes:   Start with current window.  If next window exists then go to it
  230.  *           else go to the first (top) window on screen.
  231.  *          When I added vertical windows, finding the "correct" next
  232.  *           window became extremely, unnecessarily, unmanageably complicated.
  233.  *           let's just use a simple procedure to find the first available,
  234.  *           visible, next window.
  235.  */
  236. int  next_window( TDE_WIN *window )
  237. {
  238. register TDE_WIN *wp;
  239. int  change;
  240.  
  241.    if (window != NULL) {
  242.       change = FALSE;
  243.       /*
  244.        * start with current window and look for first next
  245.        *  visible window
  246.        */
  247.       wp = window->next;
  248.       while (wp != NULL) {
  249.          if (wp->visible) {
  250.             change = TRUE;
  251.             break;
  252.          }
  253.          wp = wp->next;
  254.       }
  255.  
  256.       /*
  257.        * if we haven't found a visible window yet, go to the beginning of
  258.        *  the list until we find a visible window.
  259.        */
  260.       if (!change) {
  261.          wp = g_status.window_list;
  262.          while (wp != window) {
  263.             if (wp->visible) {
  264.                change = TRUE;
  265.                break;
  266.             }
  267.             wp = wp->next;
  268.          }
  269.       }
  270.       if (change == TRUE) {
  271.          entab_linebuff( );
  272.          un_copy_line( window->ll, window, TRUE );
  273.          g_status.current_window = wp;
  274.